package com.glink.manage.service.Impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.glink.common.contants.BaseCodeConstants;
import com.glink.common.exception.GeneralSimpleException;
import com.glink.manage.domain.VehicleAccessRelaBean;
import com.glink.manage.domain.VehicleInfoBean;
import com.glink.manage.dto.vehicle.VehicleAccessCycleSaveDTO;
import com.glink.manage.dto.vehicle.VehicleAccessIdDTO;
import com.glink.manage.dto.vehicle.VehicleAccessPageDTO;
import com.glink.manage.mapper.VehicleAccessRelaMapper;
import com.glink.manage.service.*;
import com.glink.manage.vo.vehicle.VehicleAccessPageVO;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class VehicleAccessRelaServiceImpl extends ServiceImpl<VehicleAccessRelaMapper, VehicleAccessRelaBean> implements VehicleAccessRelaService {

    @Autowired
    private UserService userService;
    
    @Autowired
    private ConstructionWorkService constructionWorkService;
    
    @Autowired
    @Lazy
    private VehicleService vehicleService;
    
    @Autowired
    @Lazy
    private BarrierGateService barrierGateService;

    /**
     * 分页查询准入
     * @param VehicleAccessPageDTO 查询条件
     * @return 信息
     */
    @Override
    public IPage<VehicleAccessPageVO> pageByAccess(VehicleAccessPageDTO VehicleAccessPageDTO) throws GeneralSimpleException {
        IPage<VehicleAccessRelaBean> iPage = new Page<>(VehicleAccessPageDTO.getPage(), VehicleAccessPageDTO.getSize());

        IPage<VehicleAccessRelaBean> accessRelaBeanIPage = this.lambdaQuery()
                .eq(VehicleAccessRelaBean::getVehicleId, VehicleAccessPageDTO.getVehicleObjId())
                .orderByDesc(VehicleAccessRelaBean::getCreateTime)
                .orderByDesc(VehicleAccessRelaBean::getObjId)
                .page(iPage);

        IPage<VehicleAccessPageVO> pageVOIPage = new Page<>(accessRelaBeanIPage.getCurrent(), accessRelaBeanIPage.getSize(), accessRelaBeanIPage.getTotal());
        List<VehicleAccessPageVO> pageVOList = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(accessRelaBeanIPage.getRecords())) {

            List<String> workIdList = Lists.newArrayList();
            boolean generalContractingUnit = userService.checkGeneralContractingUnit();
            if(generalContractingUnit){
                workIdList = constructionWorkService.findGeneralContractingUnitAccessWorkId();
                workIdList = workIdList == null ? Lists.newArrayList() : workIdList;
            }

            List<String> finalWorkIdList = workIdList;
            accessRelaBeanIPage.getRecords().forEach(accessRelaBean -> {
                VehicleAccessPageVO accessPageVO = new VehicleAccessPageVO();
                accessPageVO.setObjId(accessRelaBean.getObjId());
                accessPageVO.setConstructionWorkObjId(accessRelaBean.getConstructionWorkObjId());
                accessPageVO.setCycleStart(accessRelaBean.getCycleStart());
                accessPageVO.setCycleEnd(accessRelaBean.getCycleEnd());
                if(StringUtils.isNotBlank(accessRelaBean.getConstructionWorkObjId())){
                    accessPageVO.setConstructionWorkObjName(constructionWorkService.findNameByObjId(accessRelaBean.getConstructionWorkObjId()));
                }

                if(finalWorkIdList.contains(accessRelaBean.getConstructionWorkObjId())){
                    accessPageVO.setIfGeneralContracting(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01);
                }else{
                    accessPageVO.setIfGeneralContracting(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02);
                }
                pageVOList.add(accessPageVO);
            });
            pageVOIPage.setRecords(pageVOList);
        }
        return pageVOIPage;
    }

    /**
     * 删除
     * @param vehicleAccessIdDTO 删除条件
     * @return 状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean delAccessWork(VehicleAccessIdDTO vehicleAccessIdDTO) {
        VehicleAccessRelaBean vehicleAccessRelaBean = this.lambdaQuery().eq(VehicleAccessRelaBean::getObjId, vehicleAccessIdDTO.getAccessObjId()).one();
        if(Objects.nonNull(vehicleAccessRelaBean)){
            return removeById(vehicleAccessIdDTO.getAccessObjId());
        }else{
            return false;
        }
    }

    /**
     * 更新
     * @param vehicleAccessCycleSaveDTO 更新信息
     * @return 状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean updateAccessCycle(VehicleAccessCycleSaveDTO vehicleAccessCycleSaveDTO) {
        VehicleAccessRelaBean vehicleAccessRelaBean = this.lambdaQuery().eq(VehicleAccessRelaBean::getObjId, vehicleAccessCycleSaveDTO.getAccessObjId()).one();
        if (Objects.nonNull(vehicleAccessRelaBean)) {
            vehicleAccessRelaBean.setCycleStart(vehicleAccessCycleSaveDTO.getCycleStart());
            vehicleAccessRelaBean.setCycleEnd(vehicleAccessCycleSaveDTO.getCycleEnd());

            boolean status = updateById(vehicleAccessRelaBean);
            if(status){
                VehicleInfoBean vehicleInfoBean = vehicleService.getById(vehicleAccessRelaBean.getVehicleId());
                if(Objects.nonNull(vehicleInfoBean)){
                    barrierGateService.issuedCarAdd(vehicleInfoBean.getLicensePlate(), vehicleAccessCycleSaveDTO.getCycleStart(), vehicleAccessCycleSaveDTO.getCycleEnd(), vehicleAccessRelaBean.getConstructionWorkObjId());
                }
            }
            
            return status;
        } else {
            return false;
        }
    }

    /**
     * 删除准入
     *
     * @param constructionWorkObjId  工程
     * @param participatingUnitObjId 参建单位
     * @param nowDate                当前时间
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean delAccessByWorkObjIdAndUnitObjIdAndCycleStartGt(String constructionWorkObjId, String participatingUnitObjId, String nowDate) {
        this.baseMapper.delAccessByWorkObjIdAndUnitObjIdAndCycleStartGt(constructionWorkObjId, participatingUnitObjId, nowDate);
        return true;
    }

    /**
     * 更新准入
     *
     * @param constructionWorkObjId  工程
     * @param participatingUnitObjId 参建单位
     * @param nowDate                当前时间
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updateAccessCycleEndByWorkObjIdAndUnitObjIdAndCycleStartGtAndCycleEndLt(String constructionWorkObjId, String participatingUnitObjId, String nowDate) {
        this.baseMapper.updateAccessCycleEndByWorkObjIdAndUnitObjIdAndCycleStartGtAndCycleEndLt(constructionWorkObjId, participatingUnitObjId, nowDate);
    }

    /**
     * 根据工程查询准入的车辆
     *
     * @param workId 工程ID
     * @return 准入的车辆ID
     */
    @Override
    public List<String> findVehicleIdByWorkId(String workId) {
        List<VehicleAccessRelaBean> vehicleAccessRelaBeanList = this.lambdaQuery().eq(VehicleAccessRelaBean::getConstructionWorkObjId, workId).list();
        if(CollectionUtils.isNotEmpty(vehicleAccessRelaBeanList)){
            return vehicleAccessRelaBeanList.stream().map(VehicleAccessRelaBean::getVehicleId).collect(Collectors.toList());
        }
        return null;
    }

    /**
     * 根据车辆信息查询准入的工程
     *
     * @param vehicleId 车辆ID
     * @return 准入工程ID
     */
    @Override
    public List<String> findWorkIdByPersonId(String vehicleId) {
        List<VehicleAccessRelaBean> accessRelaBeanList = this.lambdaQuery().eq(VehicleAccessRelaBean::getVehicleId, vehicleId).list();
        if(CollectionUtils.isNotEmpty(accessRelaBeanList)){
            return accessRelaBeanList.stream().map(VehicleAccessRelaBean::getConstructionWorkObjId).collect(Collectors.toList());
        }
        return null;
    }

    /**
     * 根据工程查询准入信息
     *
     * @param constructionWorkObjId 工程ID
     * @param dateTime              时间
     * @return 准入信息
     */
    @Override
    public List<VehicleAccessRelaBean> findAccessInfoByCycleEndGe(String constructionWorkObjId, DateTime dateTime) {
        
        return this.lambdaQuery().eq(VehicleAccessRelaBean::getConstructionWorkObjId, constructionWorkObjId)
                .ge(VehicleAccessRelaBean::getCycleEnd, dateTime)
                .list();
    }

    /**
     * 根据车辆信息查询准入信息
     *
     * @param vehicleId 车辆ID
     * @param dateTime  时间
     * @return 准入信息
     */
    @Override
    public List<VehicleAccessRelaBean> findAccessInfoByVehicleIdAndCycleEndGe(String vehicleId, DateTime dateTime) {
        return this.lambdaQuery().eq(VehicleAccessRelaBean::getVehicleId, vehicleId)
                .ge(VehicleAccessRelaBean::getCycleEnd, dateTime)
                .list();
    }
}
